#include <QtDebug>

#include <io/buffercache.h>

BufferCache BufferCache::sInstance(DEF_MAX_SIZE);

BufferCache::Item::Item(char* buff, int len) :
    buff(buff),
    len(len)
{
}

BufferCache::BufferCache(int maxSize, QObject *parent) :
    QObject (parent),
    mMaxSize(maxSize),
    mBufferCount(0)
{
}

char* BufferCache::get(int len) {
    mLock.lock();

    // try find buff from cache
    char* buff = nullptr;
    for (Item item : mBuffers) {
        if (item.len >= len) {
            buff = item.buff;
            break;
        }
    }

    // check for create
    if (buff == nullptr) {
        buff = new char[len];
        mBuffers.push_front(Item(buff, len));
        mBufferCount ++;
        qDebug() << "BufferCache::get()# create a buffer with len: " << len << ". Current buffer count: " << mBufferCount;
    }

    mLock.unlock();
    return buff;
}

void BufferCache::put(char* buff, int len) {
    mLock.lock();

    // remove item if more than max size
    if (mBufferCount >= mMaxSize) {
        Item item = mBuffers.takeLast();
        delete[] item.buff;
        mBufferCount --;
        qDebug() << "BufferCache::get()# delete a buffer with len: " << item.len << ". Current buffer count: " << mBufferCount;
    }

    // cache buff
    mBuffers.push_front(Item(buff, len));
    mBufferCount ++;

    mLock.unlock();
}

BufferCache& BufferCache::instance() {
    return sInstance;
}
